package com.weijian.manager;

import io.minio.*;
import io.minio.http.Method;
import io.minio.messages.Item;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Component
@RequiredArgsConstructor
public class MinioManager {

    private final MinioClient minioClient;

    private final int DEFAULT_EXPIRE_TIME = 20;

    @Value("${minio.bucket-name}")
    private String bucketName;

    /**
     * 上传文件
     *
     * @param file 文件
     * @param key  对象键
     * @return 文件访问URL
     */
    public String uploadFile(MultipartFile file, String key) throws Exception {
        try (InputStream inputStream = file.getInputStream()) {
            minioClient.putObject(
                    PutObjectArgs.builder()
                            .bucket(bucketName)
                            .object(key)
                            .stream(inputStream, file.getSize(), -1)
                            .contentType(file.getContentType())
                            .build()
            );
        }
        return getFileUrl(key);
    }


    /**
     * 检查文件是否已存在于MinIO中
     *
     * @param key 对象键（通常是基于文件MD5值的键）
     * @return true表示文件存在，false表示文件不存在
     */
    public boolean fileExists(String key) throws Exception {
        try {
            minioClient.statObject(
                    StatObjectArgs.builder()
                            .bucket(bucketName)
                            .object(key)
                            .build());
            return true; // 文件存在
        } catch (Exception e) {
            // 如果是文件不存在的异常，则返回false
            if (e.getMessage().contains("NoSuchKey") || e.getMessage().contains("not exist")) {
                return false;
            }
            // 其他异常则重新抛出
            throw e;
        }
    }


    /**
     * 获取文件访问URL
     *
     * @param key 对象键
     * @return 文件访问URL
     */
    public String getFileUrl(String key) throws Exception {
        return getFileUrl(key, DEFAULT_EXPIRE_TIME);
    }

    /**
     * 获取文件访问URL并且设置逻辑过期时间
     *
     * @param key 对象键
     * @return 文件访问URL
     */
    public String getFileUrl(String key, int expireMinutes) throws Exception {
        return minioClient.getPresignedObjectUrl(
                GetPresignedObjectUrlArgs.builder()
                        .method(Method.GET)
                        .bucket(bucketName)
                        .object(key)
                        .expiry(expireMinutes, TimeUnit.MINUTES) // 24小时有效期
                        .build());
    }


    /**
     * 删除文件
     */
    public void delete(String objectName) throws Exception {
        minioClient.removeObject(
                RemoveObjectArgs.builder()
                        .bucket(bucketName)
                        .object(objectName)
                        .build());
    }

    /**
     * 列出桶内所有文件（可分页）
     */
    public List<Item> list() throws Exception {
        Iterable<Result<Item>> results = minioClient.listObjects(
                ListObjectsArgs.builder().bucket(bucketName).build());
        List<Item> list = new ArrayList<>();
        for (Result<Item> r : results) list.add(r.get());
        return list;
    }
}
